package cn.shen.sheng.da.controller;

import cn.shen.sheng.da.common.ServerResponse;
import cn.shen.sheng.da.model.entity.CourseEntity;
import cn.shen.sheng.da.service.ClassTaskService;
import cn.shen.sheng.da.service.CourseService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Api(tags = "基于遗传算法排课功能接口")
@RestController
@RequestMapping("/admin/course")
public class ClassTaskController {
    /**
     * 获得学期集合,如：
     * 2019-2020-1
     * 2019-2020-2
     *
     * @return
     */

    @Autowired
    private CourseService service;
    @Autowired
    private ClassTaskService classTaskService;
    @ApiOperation(value = "获得学期集合",notes = "2020-2")
    @GetMapping("/term")
    public ServerResponse queryAllSemester() {
        QueryWrapper<CourseEntity> classEntityQueryWrapper = new QueryWrapper<CourseEntity>();
        classEntityQueryWrapper.select("term").groupBy("term");
        List<CourseEntity> list = service.list(classEntityQueryWrapper);
        List<Map<String, String>> termList = new ArrayList<>();
        for (CourseEntity term1 : list){
            Map<String, String> map = new HashMap<>();
            map.put("term", term1.getTerm());

            termList.add(map);
        }
        return ServerResponse.ofSuccess(termList);
    }

    /**
     * 排课算法接口，传入学期开始去查对应学期的开课任务，进行排课，排完课程后添加到schedules表
     *
     * @param
     * @return
     */
    @ApiOperation(value = "排课算法接口，传入(学期),(开始排课时间)开始去查对应学期的开课任务，进行排课，排完课程后添加到schedules表",notes = "遗传算法分两大步骤：编码和解码\n1.确定每个基因位数对确定取到基因，以及简单逻辑基因进行编码,确定遗传代数，设置突变率，设置期望值，以便计算种群舒适度\n2.基因编码后形成染色体(个体)，添加对应信息到染色体上\n3、给初始基因编码随机分配时间，得到同班上课时间不冲突的编码\n4、将分配好时间的基因编码以班级分类成为以班级的个体，得到班级的不冲突时间初始编码\n5、遗传进化:包括选择、交叉、变异、冲突检测，消除冲突，直到达到终止条件\n6、解码最终的染色体获取其中的基因信息,并写入数据库 \n 排课问题描述\n" +
            "\n" +
            "            目前高校排课问题具有以下特征：每学期一个班级要上多门课程，每个班级上课的教室不固定，一门课程由一个或多个教师教授，一个教师可以上一门或多门课程。每门课程根据学时总数决定每周授课的次数和每次授课的节数。\n" +
            "\n" +
            "            为了描述方便，将每次授课涉及的元素(课程，班级列表，教师，周学时)称作课元，将一周内可供授课的时间划分为时间片，最小的时间片为一节课，将(时间片，教室)组成的有序对称为时空片。对同一个教室的时空片，若其时间片连续，则将这组时空片称为时空片簇。所以排课的任务就是要为所有的课元安排合理的时空片簇。求解排课问题就是要在满足全部硬约束条件的情况下，为所有课元按照每门课程课时总数的要求，为其分配互不相交的时空片簇，从而获得问题的可行解，即一张满意的课表"
    )
    @PostMapping("/arrange/{term}/{classDates}")
    public ServerResponse arrange(@PathVariable("term") String term ,@PathVariable("classDates")List<String> classDates) {
        return classTaskService.classScheduling(term,classDates);
    }
}
